api-overview.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import { useCallback } from 'react'
  2. import {
  3. ErrorCountsChartRenderer,
  4. NetworkTrafficRenderer,
  5. RequestsByCountryMapRenderer,
  6. ResponseSpeedChartRenderer,
  7. TopApiRoutesRenderer,
  8. TotalRequestsChartRenderer,
  9. } from '@/components/interfaces/Reports/renderers/ApiRenderers'
  10. import ReportFilterBar from '@/components/interfaces/Reports/ReportFilterBar'
  11. import ReportHeader from '@/components/interfaces/Reports/ReportHeader'
  12. import ReportPadding from '@/components/interfaces/Reports/ReportPadding'
  13. import { REPORT_DATERANGE_HELPER_LABELS } from '@/components/interfaces/Reports/Reports.constants'
  14. import ReportStickyNav from '@/components/interfaces/Reports/ReportStickyNav'
  15. import ReportWidget from '@/components/interfaces/Reports/ReportWidget'
  16. import { DatePickerValue } from '@/components/interfaces/Settings/Logs/Logs.DatePickers'
  17. import UpgradePrompt from '@/components/interfaces/Settings/Logs/UpgradePrompt'
  18. import DefaultLayout from '@/components/layouts/DefaultLayout'
  19. import ObservabilityLayout from '@/components/layouts/ObservabilityLayout/ObservabilityLayout'
  20. import { ObservabilityLink } from '@/components/ui/ObservabilityLink'
  21. import { useApiReport } from '@/data/reports/api-report-query'
  22. import { useReportDateRange } from '@/hooks/misc/useReportDateRange'
  23. import type { NextPageWithLayout } from '@/types'
  24. export const ApiReport: NextPageWithLayout = () => {
  25. const report = useApiReport()
  26. const {
  27. data,
  28. error,
  29. filters,
  30. isLoading,
  31. params,
  32. mergeParams,
  33. removeFilters,
  34. addFilter,
  35. refresh,
  36. } = report
  37. const {
  38. datePickerHelpers,
  39. datePickerValue,
  40. handleDatePickerChange: handleDatePickerChangeFromHook,
  41. showUpgradePrompt,
  42. setShowUpgradePrompt,
  43. } = useReportDateRange(REPORT_DATERANGE_HELPER_LABELS.LAST_60_MINUTES)
  44. const handleDatepickerChange = useCallback(
  45. (vals: DatePickerValue) => {
  46. const promptShown = handleDatePickerChangeFromHook(vals)
  47. if (!promptShown) {
  48. mergeParams({
  49. iso_timestamp_start: vals.from ?? '',
  50. iso_timestamp_end: vals.to ?? '',
  51. })
  52. }
  53. },
  54. [handleDatePickerChangeFromHook, mergeParams]
  55. )
  56. const handleDatepickerChangeForRefresh = useCallback(
  57. (vals: DatePickerValue) => {
  58. handleDatePickerChangeFromHook(vals)
  59. mergeParams({
  60. iso_timestamp_start: vals.from ?? '',
  61. iso_timestamp_end: vals.to ?? '',
  62. })
  63. handleDatepickerChange(vals)
  64. },
  65. [handleDatePickerChangeFromHook, mergeParams, handleDatepickerChange]
  66. )
  67. const refreshWithParams = useCallback(async () => {
  68. await new Promise((resolve) => setTimeout(resolve, 0))
  69. refresh()
  70. }, [refresh])
  71. const onRefreshReport = useCallback(async () => {
  72. if (datePickerValue.isHelper && datePickerValue.text) {
  73. const selectedHelper = datePickerHelpers.find((h) => h.text === datePickerValue.text)
  74. if (selectedHelper) {
  75. handleDatepickerChangeForRefresh({
  76. from: selectedHelper.calcFrom(),
  77. to: selectedHelper.calcTo(),
  78. isHelper: true,
  79. text: selectedHelper.text,
  80. })
  81. }
  82. }
  83. await refreshWithParams()
  84. }, [datePickerValue, datePickerHelpers, handleDatepickerChangeForRefresh, refreshWithParams])
  85. return (
  86. <ReportPadding>
  87. <ReportHeader title="API Gateway" showDatabaseSelector={false} />
  88. <ReportStickyNav
  89. content={
  90. <div className="flex items-center gap-3">
  91. <ReportFilterBar
  92. onRemoveFilters={removeFilters}
  93. onDatepickerChange={handleDatepickerChange}
  94. datepickerFrom={params.totalRequests.iso_timestamp_start}
  95. datepickerTo={params.totalRequests.iso_timestamp_end}
  96. onAddFilter={addFilter}
  97. onRefresh={onRefreshReport}
  98. isLoading={isLoading}
  99. filters={filters}
  100. datepickerHelpers={datePickerHelpers}
  101. initialDatePickerValue={datePickerValue}
  102. className="w-full"
  103. showDatabaseSelector={false}
  104. />
  105. <UpgradePrompt
  106. show={showUpgradePrompt}
  107. setShowUpgradePrompt={setShowUpgradePrompt}
  108. title="Report date range"
  109. description="Report data can be stored for a maximum of 3 months depending on the plan that your project is on."
  110. source="apiReportDateRange"
  111. />
  112. </div>
  113. }
  114. >
  115. <ReportWidget
  116. isLoading={isLoading}
  117. params={params.requestsByCountry}
  118. error={error.requestsByCountry}
  119. title="Requests by Geography"
  120. tooltip="Number of API Gateway requests per geography"
  121. data={data.requestsByCountry || []}
  122. renderer={RequestsByCountryMapRenderer}
  123. contentClassName="p-0 overflow-hidden"
  124. headerClassName="px-4 pt-4"
  125. />
  126. <ReportWidget
  127. isLoading={isLoading}
  128. params={params.totalRequests}
  129. title="Total Requests"
  130. data={data.totalRequests || []}
  131. error={error.totalRequest}
  132. renderer={TotalRequestsChartRenderer}
  133. append={TopApiRoutesRenderer}
  134. appendProps={{ data: data.topRoutes || [], params: params.topRoutes }}
  135. />
  136. <ReportWidget
  137. isLoading={isLoading}
  138. params={params.errorCounts}
  139. title="Response Errors"
  140. tooltip="Error responses with 4XX or 5XX status codes"
  141. data={data.errorCounts || []}
  142. error={error.errorCounts}
  143. renderer={ErrorCountsChartRenderer}
  144. appendProps={{
  145. data: data.topErrorRoutes || [],
  146. params: params.topErrorRoutes,
  147. }}
  148. append={TopApiRoutesRenderer}
  149. />
  150. <ReportWidget
  151. isLoading={isLoading}
  152. params={params.responseSpeed}
  153. title="Response Speed"
  154. tooltip="Average response speed of a request (in ms)"
  155. data={data.responseSpeed || []}
  156. error={error.responseSpeed}
  157. renderer={ResponseSpeedChartRenderer}
  158. appendProps={{ data: data.topSlowRoutes || [], params: params.topSlowRoutes }}
  159. append={TopApiRoutesRenderer}
  160. />
  161. <ReportWidget
  162. isLoading={isLoading}
  163. params={params.networkTraffic}
  164. error={error.networkTraffic}
  165. title="Network Traffic"
  166. tooltip="Ingress and egress of requests and responses respectively"
  167. data={data.networkTraffic || []}
  168. renderer={NetworkTrafficRenderer}
  169. />
  170. </ReportStickyNav>
  171. <div className="py-8">
  172. <ObservabilityLink />
  173. </div>
  174. </ReportPadding>
  175. )
  176. }
  177. ApiReport.getLayout = (page) => (
  178. <DefaultLayout>
  179. <ObservabilityLayout title="API Gateway">{page}</ObservabilityLayout>
  180. </DefaultLayout>
  181. )
  182. export default ApiReport